package com.hzhanghuan.recyclerview.adapter;

import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 适配器事务类,批量修改适配器数据,使用事务防止由于适配器数据变化导致的数据错位
 * Created by Administrator on 2016/5/23.
 */
public class AdapterTransaction<T> {

    //适配器
    private BaseAdapter<T, ? extends RecyclerView.ViewHolder> adapter;
    //操作列表
    private List<Operation> operations = new ArrayList<>();


    public AdapterTransaction(BaseAdapter<T, ? extends RecyclerView.ViewHolder> adapter) {
        this.adapter = adapter;
    }


    /**
     * 删除item
     *
     * @param index
     * @return
     */
    public AdapterTransaction<T> delete(int index) {
        operations.add(new Delete(index));
        return this;
    }


    /**
     * 删除item
     *
     * @param item
     * @return
     */
    public AdapterTransaction<T> delete(T item) {
        operations.add(new Delete(item));
        return this;
    }


    /**
     * 添加item
     *
     * @param item
     * @return
     */
    public AdapterTransaction<T> add(T item) {
        operations.add(new Add(item));
        return this;
    }


    /**
     * 添加item
     *
     * @param itemGroup
     * @return
     */
    public AdapterTransaction<T> addAll(Collection<? extends T> itemGroup) {
        operations.add(new AddAll(itemGroup));
        return this;
    }


    /**
     * 插入item
     *
     * @param index
     * @param item
     * @return
     */
    public AdapterTransaction<T> insert(int index, T item) {
        operations.add(new Insert(index, item));
        return this;
    }


    /**
     * 插入item
     *
     * @param index
     * @param itemGroup
     * @return
     */
    public AdapterTransaction<T> insertAll(int index, Collection<? extends T> itemGroup) {
        operations.add(new Insert(index, itemGroup));
        return this;
    }


    /**
     * 通知item改变
     *
     * @param item
     * @return
     */
    public AdapterTransaction<T> change(T item) {
        operations.add(new Change(item));
        return this;
    }


    /**
     * 通知item改变
     *
     * @param index
     * @return
     */
    public AdapterTransaction<T> change(int index) {
        operations.add(new Change(index));
        return this;
    }


    public AdapterTransaction<T> clear() {
        operations.add(new Clear());
        return this;
    }


    /**
     * 提交变化
     */
    public void commit() {
        for (int i = 0; i < operations.size(); i++) {
            Operation operation = operations.get(i);
            operation.action();
        }
    }


    interface Operation {
        void action();
    }


    /**
     * 删除元素
     */
    class Delete implements Operation {

        private T item;


        public Delete(T item) {
            this.item = item;
        }


        public Delete(int index) {
            this(adapter.getItem(index));
        }


        @Override
        public void action() {
            adapter.remove(item);
        }
    }


    class Add implements Operation {

        private T item;


        public Add(T item) {
            this.item = item;
        }


        @Override
        public void action() {
            adapter.add(item);
        }
    }

    class AddAll implements Operation {


        private Collection<? extends T> items;


        public AddAll(Collection<? extends T> items) {
            this.items = items;
        }


        @Override
        public void action() {
            adapter.addAll(items);
        }
    }

    class Insert implements Operation {


        private int index;
        private Collection<? extends T> items;


        public Insert(int index, T item) {
            this.index = index;
            List<T> items = new ArrayList<>();
            items.add(item);
            this.items = items;
        }


        public Insert(int index, Collection<? extends T> item) {
            this.index = index;
            this.items = item;
        }


        @Override
        public void action() {
            adapter.insertAll(index, items);
        }
    }

    class Change implements Operation {

        private T item;


        public Change(T item) {
            this.item = item;
        }


        public Change(int index) {
            this(adapter.getItem(index));
        }


        @Override
        public void action() {
            adapter.changed(item);
        }
    }


    class Clear implements Operation{

        @Override
        public void action() {
            adapter.clear();
        }
    }


}
